//
// Created by hjie on 23-7-16.
//

#include "user_association_manager.h"
#include "data_manager.h"

UserAssociationManager::UserAssociationManager(DataManager *data_manager)
{
    m_data_manager = data_manager;
}

UserAssociationManager::~UserAssociationManager()
{
    m_user_association_map.clear();
    printf("destructor %s.\n", __func__ );

}

bool UserAssociationManager::AddPublishTarget(const std::string &user_id, const std::string &target_user_id)
{
    auto iter_data = m_user_association_map.find(user_id);
    if (iter_data != m_user_association_map.end())
    {
        iter_data->second->m_publish_set.insert(target_user_id);
    }
    else
    {
        auto data = std::make_shared<UserAssociation>(m_data_manager, this);
        data->m_user_id = user_id;
        data->m_publish_set.insert(target_user_id);

        m_user_association_map[data->m_user_id] = data;
    }
    return true;
}

bool UserAssociationManager::AddSubscribe(const std::string &user_id, const std::string &target_user_id)
{
    auto iter_data = m_user_association_map.find(user_id);
    if (iter_data != m_user_association_map.end())
    {
        iter_data->second->m_subscribe_set.insert(target_user_id);
    }
    else
    {
        auto data = std::make_shared<UserAssociation>(m_data_manager, this);
        data->m_user_id = user_id;
        data->m_subscribe_set.insert(target_user_id);

        m_user_association_map[data->m_user_id] = data;
    }
    return true;
}

bool UserAssociationManager::PublishStream(const std::string &user_id, bool publish)
{
    auto iter_data = m_user_association_map.find(user_id);
    if (iter_data != m_user_association_map.end())
    {
        iter_data->second->m_is_publish_stream = publish;
    }
    else
    {
        auto data = std::make_shared<UserAssociation>(m_data_manager, this);
        data->m_user_id = user_id;
        data->m_is_publish_stream = publish;

        m_user_association_map[data->m_user_id] = data;
    }
    return true;
}

std::shared_ptr<UserAssociation> UserAssociationManager::FindUserAssociation(const std::string &user_id)
{
    auto iter = m_user_association_map.find(user_id);
    return iter == m_user_association_map.end() ? nullptr : iter->second;
}

bool UserAssociationManager::RemoveData(const std::string &user_id)
{
    auto iter_data = m_user_association_map.find(user_id);
    if (iter_data != m_user_association_map.end())
    {
        for (auto & data : iter_data->second->m_publish_set)
        {
            auto iter = m_user_association_map.find(data);
            if (iter != m_user_association_map.end())
            {
                iter->second->m_subscribe_set.erase(user_id);
            }
        }
        for (auto & data : iter_data->second->m_subscribe_set)
        {
            auto iter = m_user_association_map.find(data);
            if (iter != m_user_association_map.end())
            {
                iter->second->m_publish_set.erase(user_id);
            }
        }
        iter_data->second->m_is_publish_stream = false;
        iter_data->second->m_publish_set.clear();
        iter_data->second->m_subscribe_set.clear();
    }
    return true;
}

